﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using onlyconnect;
using myStuff;
using XmlConfig;
using System.Text.RegularExpressions;

namespace MyHtmlEditor
{
    public partial class MyHtmlEditor : UserControl
    {

        public string originalSource = "";
        string tempFilename = "";
        public Delegate userFunctionPointer;
        //bool tryingToSelectImgTag = false;
        XmlConfigurator config;

        public MyHtmlEditor()
        {
          
            InitializeComponent();
            htmlEditor1.IsDesignMode = true;
          
            htmlEditor1.Enabled = true;
           
        }


        public void setConfig(XmlConfigurator c)
        {
            config = c;
        }

        private void pasteToolStripButton_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.Paste();
        }

        private void cutToolStripButton_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.Cut();
        }


        private void toolBarButtonBold_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("bold", false, null);
        }

        private void toolBarButtonItalic_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("italic", false, null);
        }


        private void applyTag(string tagName)
        {
            IHTMLElement el = null;
            try
            {
                if (this.htmlEditor1.IsDesignMode)
                {
                    el = htmlEditor1.CurrentElement;
                    if (el.tagName == null || el.innerHTML == null) return;

                    if (el.tagName != "BODY" && el.tagName != tagName )
                    {
                        el.outerHTML = "<" + tagName + ">" + el.innerHTML + "</" + tagName + ">";
                    }
                    else
                    {
                        el.innerHTML = "<" + tagName + ">" + el.innerHTML + "</" + tagName + ">";
                    }
                }
            }
            catch (Exception exc)
            {
                string sMessage = "Could not apply tag: " + exc.Message;
                if (el != null)
                {
                    sMessage += " The possible reason is the the tag is " + el.tagName + ".";
                }
                MessageBox.Show(sMessage);
            }      
        }

      

        private void toolBarButtonHeading_Click(object sender, EventArgs e)
        {
            applyTag("h1");
        }

        private void H2_Click(object sender, EventArgs e)
        {
            applyTag("h2");
        }

        private void toolStripButtonH3_Click(object sender, EventArgs e)
        {
            applyTag("h3");
        }

        private void toolBarButtonRefresh_Click(object sender, EventArgs e)
        {
            refresh();
        }

        private void refresh()
        {
            string s = this.htmlEditor1.GetDocumentSource();
            TextWriter tw = new StreamWriter(htmlEditor1.filename);
            tw.Write(s);
            tw.Close();
            this.htmlEditor1.LoadDocument(s);
            this.htmlEditor1.LoadDocument(s);

            
        }

        private void copyToolStripButton_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.Copy();
        }
      


        private void insertImage(string s)
        {
            SendKeys.SendWait("{LEFT}{RIGHT}");
            IHTMLElement el = null;
            try
            {
                if (this.htmlEditor1.IsDesignMode)
                {
                    el = htmlEditor1.CurrentElement;
                    if (el.tagName == null) return;
                    string imgHtml = "<img style=\"border:1px dotted black; padding:2px;\" class=\"ScrShot\" src=\"" + s + "\" /><BR>";

                    if (el.tagName == "UL" || el.tagName == "OL")
                    {
                        string endTag = el.outerHTML.Substring(el.outerHTML.Length - 5);
                        if (endTag == "</LI>")
                            el.outerHTML = el.outerHTML.Substring(0, el.outerHTML.Length - 5) + "<br />" + imgHtml + "</li>";
                        else
                            el.innerHTML = el.innerHTML + "<li>" + imgHtml + "</li>";
                    }
                    else
                        if (el.tagName == "LI")
                        {
                            string endTag = el.outerHTML.Substring(el.outerHTML.Length - 5);
                            if (endTag == "</LI>")
                                el.outerHTML = el.outerHTML.Substring(0, el.outerHTML.Length - 5) + "<br />" + imgHtml + "</li>";
                            else
                                el.outerHTML = "<br />" + imgHtml + "</li>";
                        }
                        else if (el.tagName != "BODY")
                        {
                            el.outerHTML = el.innerHTML + imgHtml + "<br />";
                        }
                        else
                        {
                            el.innerHTML = el.innerHTML + imgHtml + "<br />";
                        }
                }

            }
            catch (Exception exc)
            {
                string sMessage = "Could not insert img: " + exc.Message;
                if (el != null)
                {
                    sMessage += " The possible reason is the the tag is " + el.tagName + ".";
                }
                MessageBox.Show(sMessage);
            }

            SendKeys.Send("{LEFT}{RIGHT}");

            //fixHtml();
            
        }

        public void fixHtml()
        {
            FileInfo f = new FileInfo(htmlEditor1.filename);
            string s = "file:///" + f.DirectoryName + "/";
            s = s.Replace("\\", "/");

            string src = htmlEditor1.GetDocumentSource();
            src = src.Replace(s, "");


            tempFilename = f.DirectoryName + "\\_" + f.Name;
            TextWriter tw = new StreamWriter(tempFilename);
            tw.Write(src);
            tw.Close();

            htmlEditor1.LoadUrl("file:///" + tempFilename);
            
        }

        public void toolStripButtonClipShot_Click(object sender, EventArgs e)
        {
            if (!Clipboard.ContainsImage())
                return; // no image

            string imageFileName = getNextImageFilename();
            
            ImageAnnotatorForm iaf = new ImageAnnotatorForm();
            if (!iaf.imageAnnotator1.pasteImage(imageFileName))
                return; //error
           
            //iaf.ShowDialog();
            if (iaf.ShowDialog() == DialogResult.OK) 
                insertImage(imageFileName);
       }

        private string getNextImageFilename()
        {
            // get the information of the directory
            //
            FileInfo f = new FileInfo(htmlEditor1.filename);
            DirectoryInfo directory = new DirectoryInfo(f.DirectoryName);

            FileInfo[] fArray = directory.GetFiles();
            int q = 0;

            for (int i = fArray.Count() - 1; i >= 0; i--)
            {
                if (fArray[i].Name.StartsWith(f.Name.Substring(0, f.Name.Length - 5) + "_"))
                {
                    string sImgNum = fArray[i].Name.Substring(f.Name.Length - 4, 9);
                    bool res = int.TryParse(sImgNum, out q);
                    if (res)
                        break;
                }
            }
            q++;
            string fn = q.ToString("000000000");

            fn = f.DirectoryName + "\\" + f.Name.Substring(0, f.Name.Length - 5) + "_" + fn + ".png";

            return fn;
        }

        private void toolStripButtonUnderline_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("underline", false, null);
        }

        private void Strikethrough_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("StrikeThrough", false, null);
        }

        private void toolStripButtonNumlist_Click(object sender, EventArgs e)
        {
            IHTMLElement el = null;
            try
            {
                if (this.htmlEditor1.IsDesignMode)
                {
                    el = htmlEditor1.CurrentElement;
                    if (el.tagName == null) return;

                    if (el.tagName != "BODY" )//&& el.tagName != "LI")
                    {
                        el.outerHTML = "<ol><li>" + el.innerHTML +"</li></ol>";
                    }
                    else
                    {
                        el.innerHTML = "<ol><li>" + el.innerHTML +"</li></ol>";
                    }
                }
            }
            catch (Exception exc)
            {
                string sMessage = "Could not apply heading: " + exc.Message;
                if (el != null)
                {
                    sMessage += " The possible reason is the the tag is " + el.tagName + ".";
                }
                MessageBox.Show(sMessage);
            }
            SendKeys.Send("{LEFT}");
        }

        private void toolStripButtonBulletlist_Click(object sender, EventArgs e)
        {
            IHTMLElement el = null;
            try
            {
                if (this.htmlEditor1.IsDesignMode)
                {
                    el = htmlEditor1.CurrentElement;
                    if (el.tagName == null) return;

                    if (el.tagName != "BODY")// && el.tagName != "LI")
                    {
                        el.outerHTML =  "<ul><li>"+ el.innerHTML + "</li></ul>";
                    }
                    else
                    {
                        el.innerHTML =  "<ul><li>"+ el.innerHTML + "</li></ul>";
                    }
                }
                SendKeys.Send("{LEFT}");
            }
            catch (Exception exc)
            {
                string sMessage = "Could not apply heading: " + exc.Message;
                if (el != null)
                {
                    sMessage += " The possible reason is the the tag is " + el.tagName + ".";
                }
                MessageBox.Show(sMessage);
            }   
        }

        private void toolStripButtonOutdent_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("Outdent", false, null);
        }

        private void toolStripButtonIndent_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("Indent", false, null);
        }

        private void toolStripButtonTable_Click(object sender, EventArgs e)
        {

            IHTMLElement el = null;
            try
            {
                if (this.htmlEditor1.IsDesignMode)
                {
                    el = htmlEditor1.CurrentElement;
                    if (el.tagName == null) return;

                    InsertLink ild = new InsertLink();
                   if (ild.ShowDialog() != DialogResult.OK)
                        return;

                    string url = ild.url;

                    if (el.tagName != "BODY")
                    {
                        el.outerHTML = el.innerHTML + "<A href=\"" + url + "\">" + ild.text + "</A>";
                    }
                    else
                    {
                        el.innerHTML = el.innerHTML + "<A href=\"" + url + "\">" + ild.text + "</A>";
                    }
                }
            }
            catch (Exception exc)
            {
                exc.ToString();

            } 
        }

        public void cleanup()
        {
            if (File.Exists(tempFilename))
                File.Delete(tempFilename);
            tempFilename = "";
        }
    

        public void loadFile(string f)
        {
            if (htmlEditor1.Enabled == false)
                htmlEditor1.Enabled = true;
            
            htmlEditor1.filename = f;
            htmlEditor1.LoadUrl("file:///" + f);

            //originalSource = htmlEditor1.GetDocumentSource();

            cleanup();
            unTouched(true);
        }

        private void editImage()
        {
            IHTMLElement el = null;
            try
            {
                if (this.htmlEditor1.IsDesignMode)
                {
                    el = htmlEditor1.CurrentElement;

                    if (el.tagName == null || el.tagName != "IMG")
                    {
                        return;
                    }
                    string sOriginal = (string)el.GetAttribute("src", 0);
                    string s = sOriginal.Replace("file:///", "");
                    s = s.Replace("%20", " ");
                    ImageAnnotatorForm iaf = new ImageAnnotatorForm();
                    string n = getNextImageFilename();
                    iaf.imageAnnotator1.setFile(s, n);

                    if (iaf.ShowDialog() != DialogResult.OK)
                    {
                        iaf.Dispose();
                        iaf = null;
                        return;
                    }
                    iaf.Dispose();
                    iaf = null;

                    System.GC.Collect();
                    System.GC.WaitForPendingFinalizers();
     
                    File.Delete(s);
                    el.SetAttribute("src", n, 0);
                }
            }
            catch (Exception exc)
            {
                string sMessage = "Could not apply heading: " + exc.Message;
                if (el != null)
                {
                    sMessage += " The possible reason is the the tag is " + el.tagName + ".";
                }
                MessageBox.Show(sMessage);
            }   
        }

        private void toolStripButtonEditImage_Click(object sender, EventArgs e)
        {
            SendKeys.SendWait("{LEFT}");
            timerTryingToSelectImgTag.Enabled = true;
            timerTryingToSelectImgTag.Start();  
        }


        public void editMode(bool yes)
        {
            if (yes)
                htmlEditor1.IsDesignMode = true;
            else
                htmlEditor1.IsDesignMode = false;
        }

        private void toolStripButtonMode_Click(object sender, EventArgs e)
        {
            if (htmlEditor1.IsDesignMode)
                htmlEditor1.IsDesignMode = false;
            else
            {
                string s = this.htmlEditor1.GetDocumentSource();
                htmlEditor1.IsDesignMode = true;
                this.htmlEditor1.LoadDocument(s);
            }
        }

        public string getSource()
        {
            return htmlEditor1.GetDocumentSource();
        }

        public void toolStripButtonSave_Click(object sender, EventArgs e)
        {
            userFunctionPointer.DynamicInvoke();
        }

        public void insertScreenShot(bool firstScreen)
        {
            if (htmlEditor1.bUnTouched) originalSource = htmlEditor1.GetDocumentSource();
            htmlEditor1.bUnTouched = false;
            
            if (htmlEditor1.Enabled == false)
            {
                MessageBox.Show("There is no open document to insert the image into!");
                return;
            }
            // Set the bitmap object to the size of the screen
            Bitmap bmpScreenshot;

            Screen screen;

            if (firstScreen)
                screen = Screen.AllScreens.First();
            else
                screen = Screen.AllScreens.Last();

            bmpScreenshot = new Bitmap(screen.Bounds.Width, screen.Bounds.Height, PixelFormat.Format32bppArgb);
            
            // Create a graphics object from the bitmap

            Graphics gfxScreenshot = Graphics.FromImage(bmpScreenshot);

            // Take the screenshot from the upper left corner to the right bottom corner

            gfxScreenshot.CopyFromScreen(screen.Bounds.X, screen.Bounds.Y, 0, 0, screen.Bounds.Size, CopyPixelOperation.SourceCopy);
            // Save the screenshot to the specified path that the user has chosen
            string s = getNextImageFilename();
            
            bmpScreenshot.Save(s, ImageFormat.Png);

            insertImage(s);
            //fixHtml();
            //refresh();
        }




        private void MyHtmlEditor_Enter(object sender, EventArgs e)
        {
            if (htmlEditor1.bUnTouched) originalSource = htmlEditor1.GetDocumentSource();
            htmlEditor1.bUnTouched = false;
        }

        public static void executeCommand(string cmd)//, int millsecTimeOut)
        {

            string filename = cmd;
            string args = "";
            if (cmd.IndexOf(" ") > 0)
            {
                filename = cmd.Substring(0, cmd.IndexOf(" "));
                args = cmd.Substring(cmd.IndexOf(" ") + 1);
            }
            System.Diagnostics.ProcessStartInfo processStartInfo =
               new System.Diagnostics.ProcessStartInfo(filename, args);
            processStartInfo.CreateNoWindow = false;
            processStartInfo.UseShellExecute = false;
            System.Diagnostics.Process process =
               System.Diagnostics.Process.Start(processStartInfo);
            int exitCode = process.ExitCode;
            process.Close();
        }


        private void htmlEditor1_DoubleClick(object sender, EventArgs e)
        {      
                SendKeys.SendWait("{LEFT}");
                timerTryingToSelectImgTag.Enabled = true;
                timerTryingToSelectImgTag.Start();     
        }

        public bool unTouched()
        {
            return htmlEditor1.bUnTouched;
        }

        public void unTouched(bool _unTouched)
        {
            htmlEditor1.bUnTouched = _unTouched;
        }

        private void timerTryingToSelectImgTag_Tick(object sender, EventArgs e)
        {
            timerTryingToSelectImgTag.Stop();
            timerTryingToSelectImgTag.Enabled = false;
            htmlEditor1.Update();
            htmlEditor1.Select();
            try
            {
                IHTMLElement el = htmlEditor1.CurrentElement;

                if (el.tagName == "IMG")
                {
                    editImage();

                }
                if (el.tagName == null || el.tagName != "A") return;
                string url = el.outerHTML;
                url = url.Substring(url.IndexOf("href=\"") + 6);
                url = url.Substring(0, url.IndexOf("\""));

                if (url.StartsWith("shell:"))
                {
                    url = url.Substring(6);
                    url = url.Replace("/", "\\");
                    url = url.Replace("%20", " ");
                    url = url.Replace("&amp;", "&");
                    url = url.Replace("%%QUOTE%%", "\"");
                    url = url.Replace("%%FSLASH%%", "/");
                    {
                        executeCommand(url);
                    }
                }
                else //if (url.StartsWith("file://"))
                {
                    System.Diagnostics.Process.Start(url);
                }
            }
            catch (Exception exc)
            {
                exc.ToString();
            } 
        }

        private void toolStripButtonHighlight_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("BackColor", false, "YELLOW");
        }

        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            refresh();
        }

        private void removeFormattingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("RemoveFormat", false, null);
        }

        private void redToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("BackColor", false, "RED");
        }

        private void yellowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("BackColor", false, "YELLOW");
        }

        private void greenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("BackColor", false, "LIME");
        }

        private void blueToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("BackColor", false, "AQUA");
        }

        private void whiteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.htmlEditor1.HtmlDocument2.ExecCommand("BackColor", false, "WHITE");
        }

        private void MyHtmlEditor_Load(object sender, EventArgs e)
        {
            if (htmlEditor1.filename == null || htmlEditor1.filename == "") return;
            TextReader tr = new StreamReader(htmlEditor1.filename);
            htmlEditor1.LoadDocument(tr.ReadToEnd());
            //originalSource = htmlEditor1.GetDocumentSource();
        }

        private void toolStripButtonPrint_Click(object sender, EventArgs e)
        {
            htmlEditor1.Print(true);
        }

        private void toolStripButtonLine_Click(object sender, EventArgs e)
        {
            IHTMLElement el = null;
            try
            {
                if (this.htmlEditor1.IsDesignMode)
                {
                    el = htmlEditor1.CurrentElement;
                    if (el.tagName == null) return;

                    if (el.tagName != "BODY")// && el.tagName != "LI")
                    {
                        el.outerHTML = el.outerHTML + "<hr>";
                    }
                    else
                    {
                        el.innerHTML = el.innerHTML + "<hr>";
                    }
                }
                SendKeys.Send("{RIGHT}");
            }
            catch (Exception exc)
            {
                string sMessage = "Could not apply heading: " + exc.Message;
                if (el != null)
                {
                    sMessage += " The possible reason is the the tag is " + el.tagName + ".";
                }
                MessageBox.Show(sMessage);
            }   
        }

        private void toolStripButtonDate_Click(object sender, EventArgs e)
        {
            DateTime dateTime = DateTime.Now;

            StringBuilder sDate = new StringBuilder();
            sDate.AppendFormat("{0:R}", dateTime);

          IHTMLElement el = null;
            try
            {
                if (this.htmlEditor1.IsDesignMode)
                {
                    el = htmlEditor1.CurrentElement;
                    if (el.tagName == null) return;

                    if (el.tagName != "BODY")// && el.tagName != "LI")
                    {
                        el.outerHTML = el.outerHTML + "<hr>" + sDate + "";
                    }
                    else
                    {
                        el.innerHTML = el.innerHTML + "<hr>" + sDate + "";
                    }
                }
                SendKeys.Send("{RIGHT}");
            }
            catch (Exception exc)
            {
                string sMessage = "Could not apply heading: " + exc.Message;
                if (el != null)
                {
                    sMessage += " The possible reason is the the tag is " + el.tagName + ".";
                }
                MessageBox.Show(sMessage);
            } 
        }

        private void pasteCodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            htmlEditor1.PasteCode();
            
        }

        public void insertClipboardData()
        {
            if (htmlEditor1.bUnTouched) originalSource = htmlEditor1.GetDocumentSource();
            htmlEditor1.bUnTouched = false;

            if (htmlEditor1.Enabled == false)
            {
                MessageBox.Show("There is no open document to insert the data into!");
                return;
            }

            if (Clipboard.ContainsImage())
            {
                Image clipboardImage;
                clipboardImage = Clipboard.GetImage();
                string s = getNextImageFilename();

                clipboardImage.Save(s, ImageFormat.Png);

                insertImage(s);
            }



        }


    }
}
